using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Life
{
    class CellView
    {
        // The image representing the collection of images used for animation
        Texture2D spriteStrip;


        // The scale used to display the sprite strip
        float scale;


        // The time since we last updated the frame
        int elapsedTime;


        // The time we display a frame until the next one
        int frameTime;


        // The number of frames that the animation contains
        int frameCount;


        // The index of the current frame we are displaying
        int currentFrame;


        // The color of the frame we will be displaying
        Color color;


        // The area of the image strip we want to display
        Rectangle sourceRect = new Rectangle();


        // The area where we want to display the image strip in the game
        Rectangle destinationRect = new Rectangle();


        // Width of a given frame
        public int FrameWidth;


        // Height of a given frame
        public int FrameHeight;


        // Position of animation (?)
        public Vector2 Position;


        private enum State
        {
            Live,
            Growing,
            Dying,
            Dead
        }
        private State _state;

        public CellView(Texture2D texture, Vector2 position, int frameWidth, int frameHeight, 
            int frameCount, int frametime, Color color, float scale, bool isLive)
        {
            // Keep a local copy of the values passed in
            this.color = color;
            this.FrameWidth = frameWidth;
            this.FrameHeight = frameHeight;
            this.frameCount = frameCount;
            this.frameTime = frametime;
            this.scale = scale;


            Position = position;
            spriteStrip = texture;


            // Set the time to zero
            elapsedTime = 0;

            if (isLive)
            {
                currentFrame = frameCount - 1;
                _state = State.Live;
            }
            else
            {
                currentFrame = 0;
                _state = State.Dead;
            }
        }

        public void Update(bool isLive)
        {
            // No gameTime means no animation
            _state = isLive ? State.Live : State.Dead;
            currentFrame = isLive ? frameCount - 1 : 0;

            UpdateRects();
        }

        public void Update(GameTime gameTime, bool isLive)
        {
            // TODO: simpler check?
            if (isLive)
            {
                switch (_state)
                {
                    case State.Dead:
                    case State.Dying:
                        _state = State.Growing;
                        elapsedTime = 0;
                        break;
                }
            }
            else // is dead
            {
                switch (_state)
                {
                    case State.Live:
                    case State.Growing:
                        _state = State.Dying;
                        elapsedTime = 0;
                        break;
                }
            }

            // Update the elapsed time
            elapsedTime += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
            
            // If the elapsed time is larger than the frame time
            // we need to switch frames
            if (elapsedTime > frameTime)
            {
                switch (_state)
                {
                    case State.Growing:
                        if (currentFrame == frameCount - 1)
                            _state = State.Live;
                        else
                            currentFrame++;
                        break;
                    case State.Dying:
                        if (currentFrame == 0)
                            _state = State.Dead;
                        else
                            currentFrame--;
                        break;
                };

                // Reset the elapsed time to zero
                elapsedTime = 0;
            }

            UpdateRects();
        }

        private void UpdateRects()
        {
            // Grab the correct frame in the image strip by multiplying the currentFrame index by the frame width
            sourceRect = new Rectangle(currentFrame * spriteStrip.Height, 0, spriteStrip.Height, spriteStrip.Height);

            // Calculate the destination frame where the image will be drawn
            destinationRect = new Rectangle((int)Position.X,
                (int)Position.Y,
                (int)(FrameWidth * scale),
                (int)(FrameHeight * scale));
        }

        // Draw the Animation Strip
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(spriteStrip, destinationRect, sourceRect, color);
        }
    }
}
